package com.un.ebs.businessObject.controller;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.TypeUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.un.ebs.businessObject.service.DbService;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.metadata.*;
import com.un.ebs.core.util.PackageUtil;
import com.un.ebs.core.util.WebResult;
import com.un.ebs.core.util.WebUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author zc
 * @ClassName DbController
 * @Description 通用增删改查
 * @Date 2021/1/12
 */
@RestController
@RequestMapping("/common/{bo}")
@Api(value = "sys-bo", description = "通用接口")
public class DbController {
    @Autowired
    private DbService dbService;

    @Autowired
    private ApplicationContext applicationContext;

    @PostMapping("/query")
    @ApiOperation(value = "通过查询", notes = "通用查询")
    public WebResult<?> query(@RequestBody Query query) {
        return WebUtils.success(dbService.query(query));
    }

    /**
     * 通用接口：全集合查询
     *
     * @param bo       业务实体对象code
     * @param sortName 排序字段（自定义排序）
     * @param params   查询参数
     * @return
     */
    @PostMapping("/list")
    @ApiOperation(value = "业务实体列表查询", notes = "业务实体列表查询")
    public WebResult<?> list(@PathVariable(name = "bo") String bo, @RequestParam(required = false) String sortName,
                             @RequestBody(required = false) Map<String, Object> params) {
        return WebUtils.success(dbService.list(bo, sortName, params));
    }

    /**
     * 通用接口：分页查询
     *
     * @param bo        业务名称编码
     * @param sortName  自定义排序字段
     * @param pageIndex 页数
     * @param pageSize  每页大小
     * @param params    查询参数
     * @return
     */
    @PostMapping("/page/list")
    @ApiOperation(value = "业务实体分页查询", notes = "业务实体分页查询")
    public WebResult<?> pageList(@PathVariable(value = "bo") String bo, @RequestParam(required = false) String sortName,
                                 @RequestParam(required = false) Integer pageIndex, @RequestParam(required = false) Integer pageSize,
                                 @RequestBody(required = false) Map<String, Object> params) {

        return WebUtils.success(dbService.pageList(bo, sortName, pageIndex, pageSize, params));
    }

    /**
     * 通用接口：按照ID查询
     *
     * @param bo
     * @param id
     * @return
     */
    @PostMapping("/{id}")
    @ApiOperation(value = "根据主键获取单个业务实体", notes = "根据主键获取单个业务实体")
    public WebResult<?> getById(@PathVariable(value = "bo") String bo, @PathVariable(value = "id") String id) {
        return WebUtils.success(dbService.getById(bo, id));
    }

    /**
     * 通用接口：按照ID查询复合对象
     *
     * @param bo
     * @param id
     * @return
     */
    @PostMapping("/getView/{id}")
    @ApiOperation(value = "根据主键获取复合业务实体", notes = "根据主键获取复合业务实体")
    public WebResult<?> getViewById(@PathVariable(value = "bo") String bo, @PathVariable(value = "id") String id) {
        return WebUtils.success(dbService.getComplexObjectById(bo, id));
    }

    /**
     * 新增
     *
     * @param bo
     * @param json
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增业务实体", notes = "新增业务实体")
    public WebResult<?> add(@PathVariable(value = "bo") String bo, @RequestBody JSONObject json) {
        return WebUtils.success(dbService.addComplexObject(bo, json));
    }

    /**
     * 修改
     *
     * @param bo
     * @param json
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "修改业务实体", notes = "修改业务实体")
    public WebResult<?> update(@PathVariable(value = "bo") String bo, @RequestBody JSONObject json) {
        return WebUtils.success(dbService.updateComplexObject(bo, json));
    }

    /**
     * 删除
     *
     * @param bo
     * @param id
     * @return
     */
    @PostMapping("/delete/{id}")
    @ApiOperation(value = "根据ID删除业务实体", notes = "根据ID删除业务实体")
    public WebResult<?> delete(@PathVariable(value = "bo") String bo, @PathVariable(value = "id") String id) {
        return WebUtils.success(dbService.delete(bo, id));
    }

    @PostMapping("/ext/{fun_name}")
    @ApiOperation(value = "扩展服务接口")
    public WebResult exec(@PathVariable(value = "bo") String bo, @PathVariable(value = "fun_name") String funName, @RequestBody JSONObject json) {
        Optional<FunctionInfo> f = PackageUtil.getServiceFunctionExt(bo).stream().filter(s -> s.getName().equals(funName)).findFirst();
        if (f.isPresent()) {
            List<ServiceFunctionExt> list =applicationContext.getBeansOfType(ServiceFunctionExt.class).entrySet()
                    .stream().map(x->x.getValue()).collect(Collectors.toList());
            for(ServiceFunctionExt ext : list){
                ServiceInfoExt ann = ext.getClass().getAnnotation(ServiceInfoExt.class);
                if(ann!=null && ann.value().equals(bo) && ann.functionName().equals(funName)){
                    Method m = ReflectUtil.getMethodByName(ext.getClass(),"exec");
                    if(PackageUtil.isJavaBaseType(TypeUtil.getFirstParamType(m).getTypeName())){
                        return ext.exec(json.get(m.getParameters()[0].getName()));
                    }else{
                        return ext.exec(json.toJavaObject(TypeUtil.getFirstParamType(m)));
                    }
                }
            }
        }
        return WebUtils.success();
    }

}
